package com.avic.modules.equipment.service.impl;

import com.avic.common.service.impl.BaseServiceImpl;
import com.avic.common.utils.QueryHelpPlus;
import com.avic.modules.equipment.domain.Equipment;
import com.avic.modules.equipment.domain.EquipmentOperation;
import com.avic.modules.equipment.domain.vo.Category;
import com.avic.modules.equipment.service.EquipmentOperationService;
import com.avic.modules.equipment.service.dto.EquipmentOperationQuery;
import com.avic.modules.equipment.service.mapper.EquipmentMapper;
import com.avic.modules.equipment.service.mapper.EquipmentOperationMapper;
import com.avic.modules.mapping.domain.DataMapping;
import com.avic.modules.mapping.domain.vo.DataMappingVo;
import com.avic.modules.mapping.service.mapper.DataMappingMapper;
import com.avic.modules.realtime.constants.RedisKeyConstant;
import com.avic.modules.statistics.domain.KanbanStatistics;
import com.avic.modules.statistics.domain.MonthlyStatistics;
import com.avic.modules.statistics.domain.MonthlyStatusRecord;
import com.avic.modules.statistics.service.KanbanStatisticsService;
import com.avic.modules.statistics.service.MonthlyStatisticsService;
import com.avic.modules.statistics.service.MonthlyStatusRecordService;
import com.avic.modules.system.domain.DictDetail;
import com.avic.modules.system.service.mapper.DictDetailMapper;
import com.avic.utils.RedisUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author zhangzikang 设备运行表
 * @date 2022-08-14
 */
@Service(value = "equipmentOperationService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class EquipmentOperationServiceImpl extends BaseServiceImpl
        <EquipmentOperationMapper, EquipmentOperation> implements EquipmentOperationService {

    // 类型
    private final Long type = 2L;
    // 子设备
    private final int auxiliary = 2;
    private final EquipmentOperationMapper equipmentOperationMapper;
    private final EquipmentMapper equipmentMapper;
    private final DataMappingMapper dataMappingMapper;
    private final RedisUtils redisUtils;
    private final KanbanStatisticsService kanbanStatisticsService;
    private final MonthlyStatisticsService monthlyStatisticsService;
    private final MonthlyStatusRecordService monthlyStatusRecordService;
    private final DictDetailMapper dictDetailMapper;

    public EquipmentOperationServiceImpl(EquipmentOperationMapper equipmentOperationMapper, EquipmentMapper equipmentMapper, DataMappingMapper dataMappingMapper, RedisUtils redisUtils, KanbanStatisticsService kanbanStatisticsService, MonthlyStatisticsService monthlyStatisticsService, MonthlyStatusRecordService monthlyStatusRecordService, DictDetailMapper dictDetailMapper) {
        this.equipmentOperationMapper = equipmentOperationMapper;
        this.equipmentMapper = equipmentMapper;
        this.dataMappingMapper = dataMappingMapper;
        this.redisUtils = redisUtils;
        this.kanbanStatisticsService = kanbanStatisticsService;
        this.monthlyStatisticsService = monthlyStatisticsService;
        this.monthlyStatusRecordService = monthlyStatusRecordService;
        this.dictDetailMapper = dictDetailMapper;
    }

    /**
     * 查询设备的运行记录
     * @param criteria
     * @return
     */
    @Override
    public Equipment queryOperation(EquipmentOperationQuery criteria) {
        String equipId = criteria.getEquipId();
        Equipment equipment = equipmentMapper.selectById(equipId);
        if(equipment==null){
            return null;
        }else {
            Date date = new Date();//现在的日期
            if(equipment.getEquipCategoryId() == type && equipment.getDeviceType() == auxiliary){
                boolean b = redisUtils.hasKey(equipment.getId());
                if(b){
                    Object o = redisUtils.get(equipment.getId());
                    DataMappingVo map = (DataMappingVo)o;
                    if(map.getName().equals("4")){
                        equipment.setEquipAlarm(map.getEquipAlarm());
                    }
                    long time = date.getTime();
                    long time1 = map.getTime();
                    long zl = (time - time1)/1000;
                    equipment.setDuration(zl);
                }
            }else {
                QueryWrapper<DataMapping> query = new QueryWrapper<>();
                query.eq("equip_id", equipment.getId());
                Set<Integer> type = new HashSet<>();
                type.add(4);
                type.add(5);
                query.in("record_type", type);
                List<DataMapping> dataMappings = dataMappingMapper.selectList(query);
                for(DataMapping map:dataMappings){
                    Long recordCate = map.getRecordCate();
                    Object obj = redisUtils.get(map.getId());
                    DataMappingVo vo = (DataMappingVo)obj;
                    if(recordCate == 22 && map.getRecordType() == 5){
                        long time = date.getTime();
                        long time1 = vo.getTime();
                        long zl = (time - time1)/1000;
                        equipment.setDuration(zl);
                    } else if((recordCate == 7 || recordCate == 6) && map.getRecordType() == 4) {
                        DictDetail dictDetail = dictDetailMapper.selectDictDetailLabel(recordCate, vo.getName());
                        if(dictDetail!=null && !dictDetail.getValue().equals("0")){
                            equipment.setEquipAlarm(dictDetail.getValue());
                        }else {
                            equipment.setEquipAlarm("");
                        }
                    }
                }
            }

            Category category = new Category();

            // 今日设备记录
            KanbanStatistics kanbanStatistics = kanbanStatisticsService.queryKanbanStatistics(equipId);
            if(kanbanStatistics!=null){
                category.setTodayShutdown(kanbanStatistics.getShutdownQuantity());
                category.setTodayEquip(kanbanStatistics.getRunningQuantity());
                category.setTodayShutdownTotalTime(kanbanStatistics.getShutdownTime());
                category.setTodayTotalTime(kanbanStatistics.getRunningTime());
            }

            // 本月设备记录
            MonthlyStatistics monthlyStatistics = monthlyStatisticsService.queryMonthlyStatistics(equipId);
            if(monthlyStatistics!=null){
                category.setMonthShutdownSum(monthlyStatistics.getMonthlyShutdown());
                category.setMonthSum(monthlyStatistics.getMonthlyOperation());
                category.setMonthShutdownTotalTime(monthlyStatistics.getMonthlyShutdownTime());
                category.setMonthTotalTime(monthlyStatistics.getMonthlyOperationTime());
            }

            List<MonthlyStatusRecord> monthlyStatusRecord = monthlyStatusRecordService.queryMonthlyStatusRecord(equipId);
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            Integer year=cal.get(Calendar.YEAR);//获取年
            Integer month = cal.get(Calendar.MONTH)+1;//获取月（月份从0开始，如果按照中国的习惯，需要加一）
            String thisMonth = null;
            if(month<10){
                thisMonth = "-" + "0" + month;
            }else {
                thisMonth = "-" + month;
            }

            Integer day=cal.get(Calendar.DAY_OF_MONTH);//获取日（月中的某一天）
            List<String> runningTime = new ArrayList<>();
            for(int i=1;i<day;i++){
                String dd = null;
                if(i<10){
                    dd = "-" + "0" + i;
                }else {
                    dd = "-" + i;
                }
                runningTime.add(year + thisMonth + dd);
            }


            List<Map<String, Object>> object = new ArrayList<>();

            for(String time:runningTime){
                List<MonthlyStatusRecord> objects = new ArrayList<>();
                for(MonthlyStatusRecord all:monthlyStatusRecord){
                    if(time.equals(all.getCreationDate())){
                        if(objects.size()<=24){ // 每天只要24份
                            objects.add(all);
                        } else {
                            break;
                        }
                    }
                }

                for(int i = objects.size();i<=24;i++){
                    MonthlyStatusRecord monthlyStatusRecord1 = new MonthlyStatusRecord();
                    monthlyStatusRecord1.setStatus(5);
                    monthlyStatusRecord1.setCreationDate("5");
                    monthlyStatusRecord1.setEquipId("5");
                    objects.add(monthlyStatusRecord1);
                }

                String substring = time.substring(5);
                Map<String, Object> map = new LinkedHashMap<>();
                map.put(substring,objects);
                object.add(map);
            }

            equipment.setEquipmentOperation(object);
            equipment.setCategory(category);
            return equipment;
        }
    }

    /**
     * 查询设备的运行记录
     * @param criteria
     * @return
     */
    @Override
    public Equipment queryOperationAll(EquipmentOperationQuery criteria) throws ParseException {
        String equipId = criteria.getEquipId();
        Equipment equipment = equipmentMapper.selectById(equipId);
        if(equipment==null){
            return null;
        }else {
            QueryWrapper<DataMapping> query = new QueryWrapper<>();
            query.eq("equip_id", equipment.getId());
            query.eq("record_type", 5).or().eq("record_type", 4);
            List<DataMapping> dataMappings = dataMappingMapper.selectList(query);
            Date date = new Date();
            for(DataMapping  map:dataMappings){
                Long recordCate = map.getRecordCate();
                Object obj = redisUtils.get(map.getId());
                DataMappingVo vo = (DataMappingVo)obj;
                if(recordCate == 22 && map.getRecordType() == 5){
                    long time = date.getTime();
                    Long time1 = vo.getTime();
                    long zl = (time - time1)/1000;
                    equipment.setDuration(zl);
                } else if((recordCate == 7 || recordCate == 6) && map.getRecordType() == 4) {
                    DictDetail dictDetail = dictDetailMapper.selectDictDetailLabel(recordCate, vo.getName());
                    if(dictDetail!=null && !dictDetail.getValue().equals("0")){
                        equipment.setEquipAlarm(dictDetail.getValue());
                    }else {
                        equipment.setEquipAlarm("");
                    }
                }


            }
            List<EquipmentOperation> list = baseMapper.selectList(QueryHelpPlus.getPredicate(EquipmentOperation.class,criteria));
            Category category = new Category();

            // 今日设备运行数
            int todayEquip = 0;
            // 今日设备关机数
            int todayShutdown = 0;
            // 本月设备运行数
            int monthSum = 0;
            // 本月设备关机数
            int monthShutdownSum = 0;

            /**
             * 本月运行情况数据
             */
            List<String> runningTimeSeries = new ArrayList<>();
            for(EquipmentOperation equip:list){
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                String format1 = simpleDateFormat.format(date);
                String format = simpleDateFormat.format(equip.getCreateTime());
                if(!runningTimeSeries.contains(format)){
                    runningTimeSeries.add(format);
                }
                Integer runningState = equip.getRunningState();
                if(runningState == 1){
                    if(format1.equals(format)){
                        todayEquip ++;
                    }
                    monthSum++;
                }else{
                    if(format1.equals(format)){
                        todayShutdown++;
                    }
                    monthShutdownSum++;
                }
            }
            List<Map<String, Object>> object = new ArrayList<>();
            for(String time:runningTimeSeries){
                String start = time + " 0:0:0";
                String end = time + " 23:59:59";
                SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date parse = formatter.parse(start);
                Date parse1 = formatter.parse(end);
                long time1 = parse.getTime();
                long time2 = parse1.getTime();
                List<EquipmentOperation> objects = new ArrayList<>();
                for(EquipmentOperation all:list){
                    long time3 = all.getCreateTime().getTime();
                    if(time3 < time2 && time3 > time1){
                        objects.add(all);
                    }
                }
                String substring = time.substring(5);
                Map<String, Object> map = new LinkedHashMap<>();
                map.put(substring,objects);
                object.add(map);
            }

            category.setTodayShutdown(todayShutdown);
            category.setTodayEquip(todayEquip);
            category.setMonthShutdownSum(monthShutdownSum);
            category.setMonthSum(monthSum);
            equipment.setEquipmentOperation(object);
            equipment.setCategory(category);
            return equipment;
        }
    }

    /**
     * 添加设备运行记录
     * @param equipId
     * @param state
     */
    @Override
    public void addOperation(String equipId, Integer state, Long time) {
        EquipmentOperation equipmentOperation = new EquipmentOperation();
        String replace = UUID.randomUUID().toString().replace("-", "");
        equipmentOperation.setId(replace);
        equipmentOperation.setEquipId(equipId);
        equipmentOperation.setRunningState(state);
        equipmentOperation.setSecond(time);
        equipmentOperation.setCreateTime(new Timestamp(System.currentTimeMillis()));
        equipmentOperationMapper.insert(equipmentOperation);
        KanbanStatistics kanbanStatistics = kanbanStatisticsService.queryKanbanStatistics(equipId);
        if(kanbanStatistics!=null){
            if(state == 1){
                redisUtils.hincr(RedisKeyConstant.MONTH_RUNNING_SUM,equipId,1);
                kanbanStatistics.setRunningQuantity(kanbanStatistics.getRunningQuantity()+1);
                kanbanStatistics.setRunningTime(kanbanStatistics.getRunningTime()+time);
            }else {
                redisUtils.hincr(RedisKeyConstant.MONTH_SHUTDOWN_SUM,equipId,1);
                kanbanStatistics.setShutdownQuantity(kanbanStatistics.getShutdownQuantity()+1);
                kanbanStatistics.setShutdownTime(kanbanStatistics.getShutdownTime()+time);
            }
            kanbanStatisticsService.eatKanbanStatistics(kanbanStatistics);
        }else {
            KanbanStatistics statistics = new KanbanStatistics();
            statistics.setCreateTime(new Timestamp(System.currentTimeMillis()));
            statistics.setEquipId(equipId);
            if(state == 1){
                redisUtils.hincr(RedisKeyConstant.MONTH_RUNNING_SUM,equipId,1);
                statistics.setRunningQuantity(1);
                statistics.setRunningTime(time);
            }else {
                redisUtils.hincr(RedisKeyConstant.MONTH_SHUTDOWN_SUM,equipId,1);
                statistics.setShutdownQuantity(1);
                statistics.setShutdownTime(time);
            }
            kanbanStatisticsService.addKanbanStatistics(statistics);
        }
    }

    /**
     * 添加记录到set
     */
    public boolean zsetAddByEquipId(String equipId, EquipmentOperation equipmentOperation){
        return redisUtils.zsetAdd(RedisKeyConstant.ZSET_QUERY.concat(equipId),equipmentOperation,equipmentOperation.getCreateTime().getTime());
    }

    @Override
    public void del() {
        equipmentOperationMapper.del();
    }

}
